package net.oschina.arvin.dbjava.util;

import net.oschina.arvin.dbjava.model.Column;
import net.oschina.arvin.dbjava.model.ModelClass;
import net.oschina.arvin.dbjava.model.ModelField;
import net.oschina.arvin.dbjava.model.Table;
import net.oschina.arvin.dbjava.table.ColumnNameToFieldConverter;
import net.oschina.arvin.dbjava.table.DefaultColumnNameToFieldConverter;
import net.oschina.arvin.dbjava.table.DefaultTablenameToModelConverter;
import net.oschina.arvin.dbjava.table.TablenameToModelConverter;

import java.util.ArrayList;
import java.util.List;

/**
 * 模型生成工具类
 *
 * @author Arvin
 * @time 2017/9/28 16:41
 */
public class ModelGenUtils {

    /**
     * 四个空格
     */
    public static final String BLANK_4 = "    ";
    /**
     * 八个空格
     */
    public static final String BLANK_8 = BLANK_4 + BLANK_4;

    /**
     * 表字段转模型字段
     *
     * @param tableColumn                数据库表字段
     * @param toBoolForLenOneNumber      是否将长度为1的TINYINT和BIT转换成boolean
     * @param wrapMode                   是否使用包装类，如int--> Integer (注意只有允许null的才会转换， 不允许null的会抛异常)
     * @param columnNameToFieldConverter 列名转换器
     * @return
     */
    public static ModelField columnToModelField(Column tableColumn, boolean toBoolForLenOneNumber, boolean useUtilDate, boolean wrapMode, ColumnNameToFieldConverter columnNameToFieldConverter) {

        Class<?> modelType = DBJavaTypeMap.getJavaTypeFromMysqlColumn(tableColumn, toBoolForLenOneNumber, useUtilDate, wrapMode);
        columnNameToFieldConverter = columnNameToFieldConverter == null ? DefaultColumnNameToFieldConverter.INSTANCE : columnNameToFieldConverter;
        String modelName = columnNameToFieldConverter.convert(tableColumn.getColumnName());

        ModelField modelField = new ModelField(modelType, modelName, tableColumn.getComment());
        modelField.setDefaultValue(tableColumn.getDefaultValue());
        modelField.setIsPrimaryKey(tableColumn.isPrimaryKey());
        modelField.setIsUnique(tableColumn.isUniqueKey());

        return modelField;
    }

    /**
     * 将多个数据库列转换成java模型属性
     *
     * @param columnList                 数据库列对象
     * @param toBoolForLenOneNumber      是否将长度为1的TINYINT和BIT转换成boolean
     * @param wrapMode                   是否使用包装类，如int--> Integer (注意只有允许null的才会转换， 不允许null的会抛异常)
     * @param columnNameToFieldConverter 列名转换器
     * @return
     */
    public static List<ModelField> columnsToModelFields(List<Column> columnList, boolean toBoolForLenOneNumber, boolean useUtilDate, boolean wrapMode, ColumnNameToFieldConverter columnNameToFieldConverter) {
        if (null == columnList || columnList.isEmpty()) {
            return new ArrayList<ModelField>();
        }
        List<ModelField> modelFieldList = new ArrayList<ModelField>();
        columnNameToFieldConverter = columnNameToFieldConverter == null ? DefaultColumnNameToFieldConverter.INSTANCE : columnNameToFieldConverter;

        for (Column column : columnList) {
            ModelField modelField = columnToModelField(column, toBoolForLenOneNumber, useUtilDate, wrapMode, columnNameToFieldConverter);
            if (null != modelField) {
                modelFieldList.add(modelField);
            }
        }

        return modelFieldList;
    }

    /**
     * 转成ModelClass对象
     *
     * @param dbUtils                    DBUtils
     * @param tablename                  表名
     * @param tablenameToModelConverter  表名转换器
     * @param columnNameToFieldConverter 列名转换器
     * @return
     */
    public static ModelClass toModelClass(DBUtils dbUtils, String tablename, boolean toBoolForLenOneNumber, boolean useUtilDate, boolean wrapMode, TablenameToModelConverter tablenameToModelConverter, ColumnNameToFieldConverter columnNameToFieldConverter) {

        Table table = dbUtils.getTable(tablename);

        List<Column> columnList = dbUtils.getTableColumns(tablename);

        // 不需要使用
        List<ModelField> modelFieldList = columnsToModelFields(columnList, toBoolForLenOneNumber, useUtilDate, wrapMode, DefaultColumnNameToFieldConverter.INSTANCE);

        tablenameToModelConverter = tablenameToModelConverter == null ? DefaultTablenameToModelConverter.INSTANCE : tablenameToModelConverter;
        String actualModelName = tablenameToModelConverter.convert(tablename);
        String tableComment = table.getComment();

        ModelClass modelClass = new ModelClass(null, actualModelName, tableComment);
        modelClass.setModelFieldList(modelFieldList);

        return modelClass;
    }

}
